package com.xeware.chatter.view;

import com.xeware.chatter.model.DFeedTrackedChanges;
import com.xeware.chatter.model.DFeedComments;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParserException;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
//import android.content.Intent;
//import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewParent;
//import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
//import android.widget.AdapterView.OnItemClickListener;

import com.xeware.chatter.R;
import com.xeware.chatter.model.Feed;
import com.xeware.chatter.model.Group;
import com.xeware.chatter.service.ConnectionManager;
//import com.xeware.chatter.util.StaticInformation;
import com.sforce.soap.partner.PartnerConnection;
import com.sforce.soap.partner.QueryResult;
import com.sforce.soap.partner.SaveResult;
import com.sforce.soap.partner.sobject.SObject;
import com.sforce.ws.ConnectionException;
import com.sforce.ws.bind.XmlObject;

public class FeedListController extends Activity {
	private static final String TAG = "Feed List Controller";

	private PartnerConnection connection;
	private List<Feed> feeds;
	private List<Group> groups;

	private Drawable trbackground;
	private boolean utron;
	private boolean gtron;
	private int etw;
	private String uid = "";
	
	@Override 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.feeds);

        EditText et = (EditText) findViewById(R.id.EditText01);
        etw = et.getWidth();
        et.setMinWidth(etw);
        et.setMaxWidth(etw);
        
        // disable groups button till implemented
        ImageButton ib = (ImageButton) findViewById(R.id.ImageButton01);
        ib.setVisibility(0); 
        
        utron = false;
        gtron = false;
        
        connection = ConnectionManager.getConnectionManager().getConnection();
        startSync();
    }
	
	public void onStartSync(View v) {
		this.startSync(); // handles call from feeds.xml obj
	}
	
	private void startSync() {
		new SyncHandler().execute();
	}
	
	private class SyncHandler extends AsyncTask<Void, Void, Void> {
		private ProgressDialog pd = new ProgressDialog(FeedListController.this);
		
		protected void onPreExecute() {  
			pd.setMessage("Syncing..."); 
			pd.setIndeterminate(true);
			pd.setCancelable(false);
			pd.show();  
		}
		 
		@Override
		protected Void doInBackground(Void... unused) {
	        feeds = getFeeds();
	        //groups = getGroups();
			return null;
		}

	    protected void onPostExecute(Void unused) {
	    	updateFeed();
	    	//updateGroups();
	    	pd.dismiss();
	    }
	}

	private List<Feed> getFeeds() {
		List<Feed> feeds = new ArrayList<Feed>();
		QueryResult result = null;
		try {
			if (uid.length()==0) { // test if 1st pass
				uid = connection.getUserInfo().getUserId();
			}
			result = connection.query("SELECT Id, Type, CreatedDate, CreatedById, CreatedBy.Name, ParentId, Parent.Name, FeedPostId, FeedPost.Body, FeedPost.Title, FeedPost.LinkURL, (SELECT Id, FieldName, OldValue, NewValue FROM FeedTrackedChanges), (SELECT Id, CreatedDate, CreatedById, CreatedBy.Name, CommentBody FROM FeedComments ORDER BY CreatedDate DESC) FROM NewsFeed ORDER BY CreatedDate DESC, Id LIMIT 10");
		} catch (NullPointerException e) {
			//Log.i(TAG, "Invalid connection");
			Feed f = new Feed("Invalid login credentials...\nPlease go back and try again..\nSuggestion: Cut and Paste the security token vs. typing it in.");
			feeds.add(f);
			return feeds;
		} catch (ConnectionException e) {
			//Log.i(TAG, e.getMessage());
			Feed f = new Feed("Error while connecting...");
			feeds.add(f);
			return feeds;
		}
		if (result.getSize() == 0) {
			Feed f = new Feed("No feed posts found...");
			feeds.add(f);
			return feeds;
		}
		
		for (SObject data : result.getRecords()) {
			try {
				Feed a = new Feed();
				String post = "";
				
				String postId = (String) data.getField("Id");
				
				String type = (String) data.getField("Type");

				XmlObject cbxml = (XmlObject) data.getField("CreatedBy");
				String author = (String) cbxml.getField("Name");
				String authorId = (String) data.getField("CreatedById");
				
				XmlObject pbxml = (XmlObject) data.getField("Parent");
				String group = (String) pbxml.getField("Name");
				String groupId = (String) pbxml.getField("ParentId");

				
				if (type.equals("TrackedChange")) {
					DFeedTrackedChanges mftc = new DFeedTrackedChanges(data);
					post = mftc.toString();
				} else if(type.equals("LinkPost")) {
					XmlObject dbxml = (XmlObject) data.getField("FeedPost");
					post = (String) dbxml.getField("Body");
					post += "\n"+ (String) dbxml.getField("Title");
					post += "\n"+ (String) dbxml.getField("LinkUrl");
				} else if(type.equals("UserStatus")) {
					author = ""; // b/c author and parent.name ie group will be same...
					XmlObject dbxml = (XmlObject) data.getField("FeedPost");
					post = (String) dbxml.getField("Body");									
				} else {
					XmlObject dbxml = (XmlObject) data.getField("FeedPost");
					post = (String) dbxml.getField("Body");					
				}
				DFeedComments dfc = new DFeedComments(data);

				String comments = dfc.toString();

				//String f = group + " -- " + author + " " + post + "\n" + comments;  
				a.setRecord(post + "\n" + comments);
				a.setId(postId);
				a.setUid(authorId);
				a.setUsername(author);
				a.setGid(groupId);
				a.setGroup(group);
				
				feeds.add(a);
			} catch (NullPointerException e) {
				// occurs 1. if feed entry doesn't have a post, 2. other causes unknown...
			}
		}
		return feeds;
	}

	public void updateFeed() {
		
		TableLayout tl = (TableLayout) findViewById(R.id.TableLayoutFeed);
		for (Feed feed : feeds) {
			TableRow tr = createFeedPostTR(feed);
			tl.addView(tr);
			tl.addView(this.getLineRow());
		}
        tl.requestLayout();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
	    //MenuInflater inflater = getMenuInflater();
	    //inflater.inflate(R.menu.feed_menu, menu); // disabling sync for now... if menu is needed for other reasons in future, we can re-enable
	    return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    // Handle item selection
	    switch (item.getItemId()) {
	    case R.id.itemSync:
	        startSync();
	        return true;
//	    case R.id.quit:
//	        quit();
//	        return true;
	    default:
	        return super.onOptionsItemSelected(item);
	    }
	}
	
	private List<Group> getGroups() {
		List<Group> groups = new ArrayList<Group>();
		try {
			String q1 = "SELECT Id, CollaborationGroup.Name FROM CollaborationGroupMember WHERE MemberId='"+uid+"'";
			QueryResult qr2 = connection.query(q1);
			if (qr2.getSize() == 0) {
				//this.notifyToast("No groups found..");
			} else {
				//this.notifyToast("You belong to "+qr2.getSize()+" groups.");
			}
		} catch (NullPointerException e) {
			Log.i(TAG, "Invalid connection");

		} catch (ConnectionException e) {
			Log.i(TAG, "CONERROR:"+e.getMessage());

		} catch (Exception e) {
			this.notifyToast("Something bad happend during query...");
			Log.i(TAG, "Error:"+ e.getMessage());
		}
		return groups;
	}

	public void onGroupsClick(View v) {
        TableLayout tl = (TableLayout) findViewById(R.id.TableLayout01);
        TableRow tr = (TableRow) findViewById(R.id.GroupRow);
		if (! gtron) {
			tr.setVisibility(0);
			gtron = true;
		} else {
	        tr.setVisibility(8);
	        gtron = false;
		}
        tl.requestLayout();
		return;		
	}

	public void onGroupClick(View v) {
		Spinner sp = (Spinner) findViewById(R.id.Spinner01);
		//sp.getSelectedItem();
		this.notifyToast("Group selected...");
		return;
	}
	
	public TableRow createFeedPostTR(Feed feed) {
		TableRow tr = new TableRow(this);
        tr.setLayoutParams(new TableRow.LayoutParams(
        		LayoutParams.FILL_PARENT,
        		LayoutParams.WRAP_CONTENT));
        
        TextView tv = new TextView(this);
        tv.setText(feed.toString());
        tv.setTag(feed); // set feed obj to tag...
        tv.setLayoutParams(new TableRow.LayoutParams(
        		LayoutParams.FILL_PARENT,
        		LayoutParams.WRAP_CONTENT
        		));
        Display display = getWindowManager().getDefaultDisplay(); 
        tv.setMaxWidth(display.getWidth()-5);        
        tv.setHorizontallyScrolling(false);
        tv.setTextColor(Color.parseColor("#2d83d5"));
        tv.setOnClickListener(new OnClickListener() {
        	public void onClick(View view) {
        		FeedListController.this.onFeedTRClick(view);	
    		}
    	});

        
        TableLayout tl = new TableLayout(this);
        TableRow itr = new TableRow(this);
        itr.addView(tv);
        tl.addView(itr);
        TableRow btr = this.getCommentRow();
        btr.setVisibility(8);
        tl.addView(btr);
        tr.addView(tl);
        return tr; // return outer tr
	}

	public TableRow getLineRow() { // makes a line...
		TableRow trline = new TableRow(this);
		trline.setLayoutParams(new TableRow.LayoutParams(
        		LayoutParams.FILL_PARENT,
        		LayoutParams.WRAP_CONTENT));
		trline.setBackgroundColor(Color.parseColor("#2d83d5"));
		trline.setMinimumHeight(2);
		trline.setWeightSum(1.0f);
		return trline;
	}
	
	public TableRow getCommentRow() {
		TableRow btr = new TableRow(this);
        btr.setLayoutParams(new TableRow.LayoutParams(
        		LayoutParams.WRAP_CONTENT,
        		LayoutParams.WRAP_CONTENT));
        LinearLayout bll = new LinearLayout(this);
        btr.setLayoutParams(new TableRow.LayoutParams(
        		LayoutParams.FILL_PARENT,
        		LayoutParams.WRAP_CONTENT));
        btr.setOrientation(0); // horizontal
        EditText et = new EditText(this);
        et.setHint("Your comment...");
        bll.addView(et);
		Button b = new Button(this);
		b.setText("Post");

		b.setGravity(Gravity.CENTER_VERTICAL);
		b.setOnClickListener(mCommentPostListener);
        Display display = getWindowManager().getDefaultDisplay();
        et.setMaxLines(1);
        et.setMaxWidth(display.getWidth()-(b.getWidth()+80));
        et.setWidth(display.getWidth()-(b.getWidth()+80));
		bll.addView(b);
		btr.addView(bll);
		return btr;
	}

	public void onFeedTRClick(View v) {
		TableRow itr = (TableRow) v.getParent();
		TableLayout itl = (TableLayout) itr.getParent();
		View iv = itl.getChildAt(1);
		if (iv.getVisibility() == 8) {
			iv.setVisibility(0);
		} else {
			iv.setVisibility(8);
		}
		itl.requestLayout();
		return;		
	}

	private OnClickListener mCommentPostListener = new OnClickListener() {
		public void onClick(View v) {
			FeedListController.this.onCommentPostClick(v);
		}
	};
	
	public void onCommentPostClick(View v) {
		LinearLayout bll = (LinearLayout) v.getParent();
		
		// need to get Feed obj.... 
		EditText et = (EditText) bll.getChildAt(0); 
		TableRow btr = (TableRow) bll.getParent();
		TableLayout tl = (TableLayout) btr.getParent();
		TableRow itr = (TableRow) tl.getChildAt(0);
		TextView tv = (TextView) itr.getChildAt(0);
		Feed f = (Feed) tv.getTag(); // feed obj
		
		String updateText = et.getText().toString();
		if (updateText.length() == 0) {
			notifyToast("Cannot post a blank status!");
			return;
		}
		
		this.notifyToast(f.getId()+" "+uid);
		
		CommentPostHandler cph = new CommentPostHandler();
		cph.setFeed(f);
		cph.setCommentRow(btr);
		cph.execute();
		
		//et.setText("");
		//notifyToast("Comment post: "+updateText+" user: "+uid);
		//Log.i(TAG, "Going to send update: "+et.getText().toString());
	}

	private class CommentPostHandler extends AsyncTask<Void, Void, Void> {
		private ProgressDialog pd = new ProgressDialog(FeedListController.this);
		private boolean success = false;
		private String message = "";
		private Feed feed = null;
		private TableRow btr = null;
		private EditText et = null;
		
		protected void setFeed(Feed f) {
			this.feed = f;
		}
		
		protected void setCommentRow(TableRow row) {
			this.btr = row;
		}
		
		protected void onPreExecute() {  
			pd.setMessage("Updating..."); 
			pd.setIndeterminate(true);
			pd.setCancelable(false);
			pd.show();  
		}
		 
		@Override
		protected Void doInBackground(Void... unused) {			
			try {
				String postid = this.feed.getId();
				String parentid = uid;
				
				LinearLayout bll = (LinearLayout) this.btr.getChildAt(0);
				this.et = (EditText) bll.getChildAt(0);
				
				
				SObject fcomment = new SObject();
				fcomment.setType("FeedComment");
				fcomment.setField("FeedItemId", postid);
				//fcomment.setField("ParentId", parentid);
				fcomment.setField("CommentBody", this.et.getText().toString());
				
				SaveResult[] results = connection.create(new SObject[] { fcomment });
				if (!results[0].isSuccess()) {
					success = false;
					message = "op error";
				} else {
					success = true;
				}
			} catch (NullPointerException e) {
				success = false;
				message = "null exception";
			} catch (ConnectionException e) {
				success = false;			
				message = "conn exception";
			}
			return null;
		}

	    protected void onPostExecute(Void unused) {
	    	pd.dismiss();
	    	if (success) {
	    		notifyToast("Comment posted.");
	    		this.et.setText("");
	    		this.btr.setVisibility(8);
	    	} else {
	    		notifyToast("Failed to post comment.");
	    		notifyToast(message);
	    	}
	    }
	}

	
	public void onUpdateClick(View v) {
		TableLayout tl = (TableLayout) findViewById(R.id.TableLayout01);
        TableRow tr = (TableRow) findViewById(R.id.UpdateRow);
		if (! utron) {
			tr.setVisibility(0);
			utron = true;
		} else {
	        tr.setVisibility(8);
	        utron = false;
		}
        tl.requestLayout();
        //tl.invalidate();
		return;
	}
	
	public void onShareClick(View v) {
		EditText et = (EditText) findViewById(R.id.EditText01);
		String updateText = et.getText().toString();
		if (updateText.length() == 0) {
			notifyToast("Cannot post a blank status!");
			return;
		}
		new UpdateHandler().execute();
		//Log.i(TAG, "Going to send update: "+et.getText().toString());
	}
	
	private class UpdateHandler extends AsyncTask<Void, Void, Void> {
		private ProgressDialog pd = new ProgressDialog(FeedListController.this);
		private boolean success = false;
		
		protected void onPreExecute() {  
			pd.setMessage("Updating..."); 
			pd.setIndeterminate(true);
			pd.setCancelable(false);
			pd.show();  
		}
		 
		@Override
		protected Void doInBackground(Void... unused) {			
			try {
				EditText et = (EditText) findViewById(R.id.EditText01);
				String updateText = et.getText().toString();
				SObject user = new SObject();
				user.setType("User");
				user.setId(connection.getUserInfo().getUserId());
				user.setField("CurrentStatus", updateText);
				SaveResult[] results = connection.update(new SObject[] { user });
				if (!results[0].isSuccess()) {
					success = false;
				} else {
					success = true;
				}
			} catch (NullPointerException e) {
				success = false;
			} catch (ConnectionException e) {
				success = false;			
			}
			return null;
		}

	    protected void onPostExecute(Void unused) {
	    	pd.dismiss();
	    	if (success) {
	    		notifyToast("Status update posted.");
	    		EditText et = (EditText) findViewById(R.id.EditText01);
	    		et.setText("");
				//startSync();
	    	} else {
	    		notifyToast("Failed to post status update.");
	    	}
	    }
	}
	
	public void notifyToast(String mesg) {
		Context context = getApplicationContext();
		int duration = Toast.LENGTH_SHORT;
		Toast toast = Toast.makeText(context, mesg, duration);
		toast.show();
	}
}
